﻿package igz.fleaxy.io
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	import igz.fleaxy.Fleaxy;
	import igz.fleaxy.util.SpriteUtil;
	
	/**
	 * @author Intelygenz | www.intelygenz.com
	 * 
	 * Gestor de eventos especial para el ratón
	 */
	public class MouseManager {

		static private var _Current : MouseManager;
		static private var _Cursor : Sprite = new Sprite();
		static private var _CenterPoint : Point;
		static private var _DefaultCursor : Boolean;
		static public function $IsDefault() : Boolean { return _DefaultCursor; }

		public function MouseManager() {
			Fleaxy.$Current.$Stage.addEventListener( MouseEvent.MOUSE_DOWN , _OnMouseDown);
			_DefaultCursor = true;
		}
		
		private function _OnMouseDown ( p_mouseEvent: MouseEvent ) : void {

			if ( p_mouseEvent.buttonDown ) {
				Fleaxy.$Current.$Stage.dispatchEvent( new Event("IgzRightClickEvent") );
			}
		}
		
		/**
		 * Añade una función cuando se pulse el botón derecho
		 * @param	f_call función a llamar
		 */
		static public function $SubscribeToRightClick ( f_call:Function ) : void {
			if ( _Current == null ) {
				_Current = new MouseManager();
			}
			Fleaxy.$Current.$Stage.addEventListener( "IgzRightClickEvent", f_call );
		}
		
		/**
		 * Elimina una función cuando se pulse el botón derecho
		 * @param	f_call función a llamar
		 */
		static public function $UnsubscribeToRightClick ( f_call:Function ) : void {
			Fleaxy.$Current.$Stage.removeEventListener( "IgzRightClickEvent", f_call );
		}

		/**
		 * Muestra el cursor 
		 * @param	p_mouseCursor tipo de cursor (ver MouseCursor.[tab]) 
		 */
		static public function $ShowCursor ( p_mouseCursor : String = MouseCursor.AUTO) : void {
			if ( _Cursor.hasEventListener(Event.ENTER_FRAME) ) {
				_Cursor.removeEventListener( Event.ENTER_FRAME, _Cursor_OnEnterFrame );
			}
			Mouse.cursor = p_mouseCursor;
			Mouse.show();
			_DefaultCursor = true;
			_Cursor.visible = false;
		}
		
		/**
		 *  Centra el cursor en el centro de un DisplayObj (o en el punto que se requiera )
		 * 
		 * @param	p_displayObject Elemento donde se quiere colocar
		 * @param	p_centerPoint Punto para centrar el cursor
		 */
		static public function $Show ( p_displayObject : DisplayObject, p_centerPoint:Point = null) : void {
			Mouse.hide();
			_DefaultCursor = false;
			_Cursor.visible = true;
			_CenterPoint = p_centerPoint==null ? new Point(0,0) : p_centerPoint;
			if (_Cursor.stage == null) {
				_Cursor.mouseEnabled = false;
				Fleaxy.$Current.$Stage.addChild(_Cursor);
			}
			SpriteUtil.$RemoveChildsOf(_Cursor);
			_Cursor.addChild(p_displayObject);
			if ( !_Cursor.hasEventListener(Event.ENTER_FRAME) ) {
				_Cursor.addEventListener( Event.ENTER_FRAME, _Cursor_OnEnterFrame);
			}
		}

		static protected function _Cursor_OnEnterFrame ( p_event : Event ) : void {
			SpriteUtil.$BringToFront(_Cursor);
			_Cursor.x = Fleaxy.$Current.$Stage.mouseX + _CenterPoint.x;
			_Cursor.y = Fleaxy.$Current.$Stage.mouseY + _CenterPoint.y;
		}

		/**
		 * Establece el cursor indicado al display object deseado.
		 * 
		 * @example
		 * 
		 * MouseManager.$SetCursorToDisplayObject( _Move, MouseCursor.HAND );
		 * MouseManager.$SetCursorToDisplayObject( _DescriptionLabel, MouseCursor.IBEAM );
		 * 
		 * @param	p_target
		 * @param	p_mouseCursor
		 */
		static public function $SetCursorToDisplayObject ( p_target:DisplayObject, p_mouseCursor : String = MouseCursor.AUTO ) : void {
			p_target.addEventListener( MouseEvent.MOUSE_OVER
									,  function ():void {
										MouseManager.$ShowCursor( p_mouseCursor );
									});

			p_target.addEventListener( MouseEvent.MOUSE_OUT
									,  function ():void {
										MouseManager.$ShowCursor( MouseCursor.AUTO );
									});
		}
	}
	
}